iT邦幫忙

2021 iThome 鐵人賽

DAY 2
1
Software Development

猴子都寫得出來的 RISC-V CPU Emulator系列 第 22

RISC-V: R-type 算術指令

  • 分享至 

  • xImage
  •  

終於進到 R-type 指令了!
指令實作已經有固定流程了,很單純,
另外花了一點時間修改昨天的 Exception。

R-type

指令格式如下:

|31     25|24   20|19   15|14    12|11   7|6       0|
+---------------------------------------------------+
|  func7  |  rs2  |  rs1  | funct3 |  rd  | opcode  |
+---------------------------------------------------+

ADD

rd = rs1 + rs2

|31         25|24   20|19   15|14    12|11   7|6       0|
+-------------------------------------------------------+
|   0000000   |  rs2  |  rs1  |  000   |  rd  | 0110011 |
+-------------------------------------------------------+

SUB

rd = rs1 - rs2

|31         25|24   20|19   15|14    12|11   7|6       0|
+-------------------------------------------------------+
|   0100000   |  rs2  |  rs1  |  000   |  rd  | 0110011 |
+-------------------------------------------------------+

實際程式

github 頁面 Tag: ITDay22

蘭尼斯特猴來還債了!
昨天只是簡單的在 ECALLEBREAK 的時候結束模擬,
相信也有讀者注意到 LOAD/STORE、JUMP/BRANCH Exception 都沒有處理,
沒做的原因是因為當時還要處理 Memory 和 Program Counter 設計的問題,
必須讓自己專注在當下最重要的事情上,於是把 Exception 相關的議題延後處理。

Exception Handling 並不屬於 Executor 的功能,
這次先轉交給 CPU,為之後的 Exception/Interrupt 實作做一點準備,
Cause 先簡單處理,之後再補上各個 Exception 的編號。

//executor.cpp
...
void EXECUTOR::ECALL_E()
{
	const int cause = 11;
	cpu->raise_exception(cause);
}

void EXECUTOR::EBREAK_E()
{
	const int cause = 3;
	cpu->raise_exception(cause);
}
...

指令部分相對單純,
這次一樣用 ADD 當範例,實作如下:

//executor.cpp
...
void EXECUTOR::reg_dispatch()
{
	switch (instruction_decoder->get_func3()) {
		case INSTRUCTION_DECODER_INTERFACE::ADDI_FN3: //SUB_FN3 is the same
			switch (instruction_decoder->get_func7()) {
				case INSTRUCTION_DECODER_INTERFACE::ADD_FN7:
					ADD_E();
					break;
...
void EXECUTOR::ADD_E()
{
	auto rd = instruction_decoder->get_rd();
	auto rs1 = instruction_decoder->get_rs1();
	auto rs2 = instruction_decoder->get_rs2();

	auto value = register_file->get_value_integer(rs1) + register_file->get_value_integer(rs2);
	register_file->set_value_integer(rd, value);
}
...
//instructionDecoderInterface.h
...
		REG_OP = 0b0110011,
...
		ADD_FN3 = 0b000,
...
		ADD_FN7 = 0b0000000,
...

上一篇
RISC-V: ECALL/EBREAK 指令
下一篇
RISC-V: R-type 位元運算指令
系列文
猴子都寫得出來的 RISC-V CPU Emulator31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言